// <editor-fold defaultstate="collapsed" desc="GNU GPLv3 Header">
/*
 * File:   Main.java
 *
 * Copyright (C) 2013 Robert Antoni Buj Gelonch <rbuj@uoc.edu>
 * Copyright (C) 2013 David Megias Jimenez <dmegias@uoc.edu>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
// </editor-fold>
package readwritewavelibwave;

// <editor-fold defaultstate="collapsed" desc="imports">
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import uoc.libwave.WaveFile;
import uoc.libwave.WaveFormatNonPCMByte;
import uoc.libwave.WaveFormatPCMByte;
import uoc.libwave.WaveFormatPCMShort;
// </editor-fold>

/**
 *
 * @author Robert Antoni Buj Gelonch <rbuj@uoc.edu>
 * @version 2.0
 * @since 2013-08-04
 */
public class Main {

    /**
     * The main class.
     *
     * @author Robert Antoni Buj Gelonch <rbuj@uoc.edu>
     * @version 1.0
     * @since 2013-08-04
     */
    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("Must supply filenames:");
            System.err.println("java -jar readwriteWave2.jar input.wav output.wav");
            System.exit(1);
        }

        String strSrcFilePath = args[0];
        String strDstFilePath = args[1];

        try {
            WaveFile wavefile = new WaveFile();
            FileInputStream fis = new FileInputStream(strSrcFilePath);
            DataInputStream dis = new DataInputStream(fis);
            // Header data
            String HeaderChunkID = wavefile.readCkID(dis);
            int HeaderChunkSize = wavefile.readCkSize(dis);
            String HeaderRiffType = wavefile.readRiffType(dis);
            // Format data
            String FormatChunkID = wavefile.readCkID(dis);
            int FormatChunkSize = wavefile.readCkSize(dis);
            short wFormatTag = wavefile.readWFormatTag(dis);
            short wChannels = wavefile.readWChannels(dis);
            int dwSamplesPerSec = wavefile.readDWSamplesPerSec(dis);
            int dwAvgBytesPerSec = wavefile.readDWAvgBytesPerSec(dis);
            short wBlockAlign = wavefile.readWBlockAlign(dis);
            short wBitsPerSample = wavefile.readWBitsPerSample(dis);
            if (wFormatTag == WaveFile.WAVE_FORMAT_PCM) {
                String DataChunkID = wavefile.readCkID(dis);
                int DataChunkSize = wavefile.readCkSize(dis);
                if (wBitsPerSample <= 8) {
                    WaveFormatPCMByte waveData = new WaveFormatPCMByte(
                            HeaderChunkID, HeaderChunkSize, HeaderRiffType,
                            FormatChunkID, FormatChunkSize, wFormatTag,
                            wChannels, dwSamplesPerSec, dwAvgBytesPerSec,
                            wBlockAlign, wBitsPerSample, DataChunkID,
                            DataChunkSize, dis);
                    waveData.saveToFile(strDstFilePath);
                } else {
                    if (wBitsPerSample <= 16) {
                        WaveFormatPCMShort waveData = new WaveFormatPCMShort(
                                HeaderChunkID, HeaderChunkSize, HeaderRiffType,
                                FormatChunkID, FormatChunkSize, wFormatTag,
                                wChannels, dwSamplesPerSec, dwAvgBytesPerSec,
                                wBlockAlign, wBitsPerSample, DataChunkID,
                                DataChunkSize, dis);
                        waveData.saveToFile(strDstFilePath);
                    } else {
                        throw new UnsupportedOperationException("Not yet implemented");
                    }
                }
            } else {
                short cbSize = wavefile.readCbSize(dis);
                if (wFormatTag != WaveFile.WAVE_FORMAT_EXTENSIBLE) {
                    String FactChunkID = wavefile.readCkID(dis);
                    int FactChunkSize = wavefile.readCkSize(dis);
                    int dwSampleLength = wavefile.readDwSampleLength(dis);
                    String DataChunkID = wavefile.readCkID(dis);
                    int DataChunkSize = wavefile.readCkSize(dis);
                    if (wBitsPerSample <= 8) {
                        WaveFormatNonPCMByte waveData = new WaveFormatNonPCMByte(
                                HeaderChunkID, HeaderChunkSize, HeaderRiffType,
                                FormatChunkID, FormatChunkSize, wFormatTag,
                                wChannels, dwSamplesPerSec, dwAvgBytesPerSec,
                                wBlockAlign, wBitsPerSample, cbSize, FactChunkID,
                                FactChunkSize, dwSampleLength, DataChunkID,
                                DataChunkSize, dis);
                        waveData.saveToFile(strDstFilePath);
                    } else {
                        throw new UnsupportedOperationException("Not yet implemented");
                    }
                } else {
                    throw new UnsupportedOperationException("Not yet implemented");
                }
            }
            dis.close();
            fis.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
